package cn.tiger.config;

import cn.tiger.util.JwtUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * JWT认证拦截器
 * 
 * 用于拦截需要认证的请求，验证JWT token的有效性
 * 并将用户信息存储到request attribute中供后续使用
 * 
 * @author AI Backend Team
 * @version 1.0
 * @since 2025-09-26
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class JwtAuthenticationInterceptor implements HandlerInterceptor {
    
    private final JwtUtil jwtUtil;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 跳过认证接口
        String requestURI = request.getRequestURI();
        if (requestURI.contains("/auth/")) {
            return true;
        }
        
        // 跳过Swagger接口
        if (requestURI.contains("/swagger") || requestURI.contains("/v3/api-docs")) {
            return true;
        }
        
        // 获取Authorization header
        String authorizationHeader = request.getHeader("Authorization");
        
        if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            response.getWriter().write("{\"code\":401,\"message\":\"未提供认证令牌\"}");
            return false;
        }
        
        // 提取token
        String token = authorizationHeader.substring(7);
        
        try {
            // 验证token
            if (!jwtUtil.validateToken(token)) {
                response.setStatus(HttpStatus.UNAUTHORIZED.value());
                response.getWriter().write("{\"code\":401,\"message\":\"认证令牌无效或已过期\"}");
                return false;
            }
            
            // 从token中提取用户信息并存储到request中
            Long userId = jwtUtil.getUserIdFromToken(token);
            String username = jwtUtil.getUsernameFromToken(token);
            String role = jwtUtil.getRoleFromToken(token);
            
            request.setAttribute("userId", userId);
            request.setAttribute("username", username);
            request.setAttribute("role", role);
            
            log.debug("用户认证成功: userId={}, username={}, role={}", userId, username, role);
            
            return true;
            
        } catch (Exception e) {
            log.error("JWT token验证失败", e);
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            response.getWriter().write("{\"code\":401,\"message\":\"认证令牌验证失败\"}");
            return false;
        }
    }
}